package com.example.admin.testdemo.rs232;

import android.content.SharedPreferences;
import android.serialport.SerialPort;

import com.example.admin.testdemo.application.App;
import com.example.admin.testdemo.util.LogUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import static android.content.Context.MODE_PRIVATE;

/**
 * 串口操作类
 *
 * @author Jerome
 */
public class Serial {
    private static String TAG = "Serial";
    private SerialPort mSerialPort;
    public OutputStream getOutputStream() {
        return mOutputStream;
    }
    public InputStream getInputStream() {
        return mInputStream;
    }
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private ReadThread mReadThread;
    private String path = "/dev/ttyS3";
    private int baudrate = 9600;
    private static Serial portUtil;
    private DataCallback onDataReceiveListener = null;
    private boolean isStop = false;

    public interface DataCallback {
        void onDataReceived(byte[] buffer, int size);
    }

    public void setCallback(
            DataCallback dataReceiveListener) {
        onDataReceiveListener = dataReceiveListener;
    }

    private Serial() {

    }

    public static Serial getSerialInstance() {

        if (portUtil == null) {
            synchronized (Serial.class) {
                if (portUtil == null) {
                    portUtil = new Serial();
                }
            }
        }


        return portUtil;
    }

    /**
     * 初始化串口信息
     */
    public void onCreate() {
        try {
            String packageName = App.getInstance().getPackageName();

            SharedPreferences sp = App.getInstance().getSharedPreferences(packageName + "_preferences", MODE_PRIVATE);
            String path = sp.getString("DEVICE", "/dev/ttyS2");
            int baudrate = Integer.decode(sp.getString("BAUDRATE", "9600"));

            mSerialPort = new SerialPort(path, baudrate, 0);
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();

            mReadThread = new ReadThread();
            isStop = false;
            mReadThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean sendBuffer(byte[] data) {
        boolean result = true;
        try {
            if (mOutputStream != null) {
                mOutputStream.write(data);
                LogUtil.e(TAG, "APP Send  :" + Command.printByteInfo(data, data.length));
            } else {
                result = false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    public void sendData(byte[] mBuffer) {
        if (!sendBuffer(mBuffer)) {
            closeSerialPort();
            onCreate();
            sendData(mBuffer);
        }
    }

    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            while (!isStop && !isInterrupted()) {
                int size;
                try {
                    if (mInputStream == null)
                        return;
                    byte[] buffer = new byte[512];
                    size = mInputStream.read(buffer);
                    if (size > 7) {
                        if (null != onDataReceiveListener) {
                            onDataReceiveListener.onDataReceived(buffer, size);
                            LogUtil.e(TAG, "APP Receive  ：" + Command.printByteInfo(buffer, size) + " Size=" + size);
                        }else {
                            LogUtil.e(TAG, "APP Receive  ：onDataReceiveListener==null");
                        }

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    /**
     * 关闭串口
     */
    public void closeSerialPort() {
        isStop = true;
        if (mReadThread != null) {
            mReadThread.interrupt();
        }
        if (mSerialPort != null) {
            try {
                mSerialPort.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}